using System;
using System.Collections.Generic;
using System.Globalization;
using UnityEngine;

namespace Lean.Localization
{
	[ExecuteInEditMode]
	public class LeanLocalization : MonoBehaviour
	{
		public enum DetectType
		{
			None,
			SystemLanguage,
			CurrentCulture,
			CurrentUICulture
		}

		[Tooltip("If the application is started and no language has been loaded or auto detected, this language will be used")]
		[LeanLanguageName]
		public string DefaultLanguage;

		[Tooltip("How should the cultures be used to detect the user's device language?")]
		public DetectType DetectLanguage = DetectType.SystemLanguage;

		[Tooltip("Automatically save/load the CurrentLanguage selection to PlayerPrefs? (can be cleared with ClearSave context menu option)")]
		public bool SaveLanguage = true;

		public List<string> Languages;

		public List<LeanCulture> Cultures;

		public List<LeanPhrase> Phrases;

		public static Action OnLocalizationChanged;

		public static List<LeanLocalization> AllLocalizations = new List<LeanLocalization>();

		private static string currentLanguage;

		private static List<string> currentLanguages = new List<string>();

		private static List<string> currentPhrases = new List<string>();

		private static Dictionary<string, LeanTranslation> currentTranslations = new Dictionary<string, LeanTranslation>();

		public static List<string> CurrentLanguages => currentLanguages;

		public static List<string> CurrentPhrases => currentPhrases;

		public static bool CurrentSaveLanguage
		{
			get
			{
				for (int num = AllLocalizations.Count - 1; num >= 0; num--)
				{
					if (AllLocalizations[num].SaveLanguage)
					{
						return true;
					}
				}
				return false;
			}
		}

		public static string CurrentLanguage
		{
			get
			{
				return currentLanguage;
			}
			set
			{
				if (CurrentLanguage != value)
				{
					currentLanguage = value;
					UpdateTranslations();
					if (CurrentSaveLanguage)
					{
						PlayerPrefs.SetString("LeanLocalization.CurrentLanguage", value);
					}
				}
			}
		}

		[ContextMenu("Clear Save")]
		public void ClearSave()
		{
			PlayerPrefs.DeleteKey("LeanLocalization.CurrentLanguage");
		}

		public void SetCurrentLanguage(string newLanguage)
		{
			CurrentLanguage = newLanguage;
		}

		public static LeanTranslation GetTranslation(string phraseName)
		{
			LeanTranslation value = null;
			if (currentTranslations != null && phraseName != null)
			{
				currentTranslations.TryGetValue(phraseName, out value);
			}
			return value;
		}

		public static string GetTranslationText(string phraseName)
		{
			return GetTranslation(phraseName)?.Text;
		}

		public static UnityEngine.Object GetTranslationObject(string phraseName)
		{
			return GetTranslation(phraseName)?.Object;
		}

		public void AddLanguage(string language, string[] aliases = null)
		{
			if (Languages == null)
			{
				Languages = new List<string>();
			}
			if (!Languages.Contains(language))
			{
				Languages.Add(language);
			}
			if (aliases == null || aliases.Length <= 0)
			{
				return;
			}
			if (Cultures == null)
			{
				Cultures = new List<LeanCulture>();
			}
			foreach (string alias in aliases)
			{
				if (!Cultures.Exists((LeanCulture c) => c.Language == language && c.Alias == alias))
				{
					LeanCulture leanCulture = new LeanCulture();
					leanCulture.Language = language;
					leanCulture.Alias = alias;
					Cultures.Add(leanCulture);
				}
			}
		}

		public LeanCulture AddCulture(string language, string alias)
		{
			if (Cultures == null)
			{
				Cultures = new List<LeanCulture>();
			}
			LeanCulture leanCulture = Cultures.Find((LeanCulture c) => c.Language == language && c.Alias == alias);
			if (leanCulture == null)
			{
				leanCulture = new LeanCulture();
				leanCulture.Language = language;
				leanCulture.Alias = alias;
				Cultures.Add(leanCulture);
			}
			return leanCulture;
		}

		public LeanPhrase AddPhrase(string phraseName)
		{
			if (Phrases == null)
			{
				Phrases = new List<LeanPhrase>();
			}
			LeanPhrase leanPhrase = Phrases.Find((LeanPhrase p) => p.Name == phraseName);
			if (leanPhrase == null)
			{
				leanPhrase = new LeanPhrase();
				leanPhrase.Name = phraseName;
				Phrases.Add(leanPhrase);
			}
			return leanPhrase;
		}

		public LeanTranslation AddTranslation(string language, string phraseName)
		{
			AddLanguage(language);
			return AddPhrase(phraseName).AddTranslation(language);
		}

		public static void UpdateTranslations()
		{
			currentTranslations.Clear();
			currentLanguages.Clear();
			currentPhrases.Clear();
			for (int i = 0; i < AllLocalizations.Count; i++)
			{
				LeanLocalization leanLocalization = AllLocalizations[i];
				if (leanLocalization.Phrases != null)
				{
					for (int num = leanLocalization.Phrases.Count - 1; num >= 0; num--)
					{
						LeanPhrase leanPhrase = leanLocalization.Phrases[num];
						string name = leanPhrase.Name;
						if (!currentPhrases.Contains(name))
						{
							currentPhrases.Add(name);
						}
						if (!currentTranslations.ContainsKey(name))
						{
							LeanTranslation leanTranslation = leanPhrase.FindTranslation(currentLanguage);
							if (leanTranslation != null)
							{
								currentTranslations.Add(name, leanTranslation);
							}
						}
					}
				}
				if (leanLocalization.Languages == null)
				{
					continue;
				}
				for (int num2 = leanLocalization.Languages.Count - 1; num2 >= 0; num2--)
				{
					string item = leanLocalization.Languages[num2];
					if (!currentLanguages.Contains(item))
					{
						currentLanguages.Add(item);
					}
				}
			}
			if (OnLocalizationChanged != null)
			{
				OnLocalizationChanged();
			}
		}

		protected virtual void OnEnable()
		{
			AllLocalizations.Add(this);
			if (string.IsNullOrEmpty(currentLanguage) && SaveLanguage)
			{
				currentLanguage = PlayerPrefs.GetString("LeanLocalization.CurrentLanguage");
			}
			if (string.IsNullOrEmpty(currentLanguage) && Cultures != null)
			{
				switch (DetectLanguage)
				{
				case DetectType.SystemLanguage:
					currentLanguage = FindLanguageName(Application.systemLanguage.ToString());
					break;
				case DetectType.CurrentCulture:
				{
					CultureInfo currentCulture = CultureInfo.CurrentCulture;
					if (currentCulture != null)
					{
						currentLanguage = FindLanguageName(currentCulture.Name);
					}
					break;
				}
				case DetectType.CurrentUICulture:
				{
					CultureInfo currentUICulture = CultureInfo.CurrentUICulture;
					if (currentUICulture != null)
					{
						currentLanguage = FindLanguageName(currentUICulture.Name);
					}
					break;
				}
				}
			}
			if (string.IsNullOrEmpty(currentLanguage))
			{
				currentLanguage = DefaultLanguage;
			}
			UpdateTranslations();
		}

		protected virtual void OnDisable()
		{
			AllLocalizations.Remove(this);
			UpdateTranslations();
		}

		private string FindLanguageName(string alias)
		{
			for (int num = Languages.Count - 1; num >= 0; num--)
			{
				string text = Languages[num];
				if (text == alias)
				{
					return text;
				}
			}
			for (int num2 = Cultures.Count - 1; num2 >= 0; num2--)
			{
				LeanCulture leanCulture = Cultures[num2];
				if (leanCulture != null && leanCulture.Alias == alias)
				{
					return leanCulture.Language;
				}
			}
			return null;
		}
	}
}
